package com.xuecheng.media.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.media.mapper.MediaProcessHistoryMapper;
import com.xuecheng.media.mapper.MediaProcessMapper;
import com.xuecheng.media.model.po.MediaProcess;
import com.xuecheng.media.model.po.MediaProcessHistory;
import com.xuecheng.media.service.MediaProcessService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;

@Slf4j
@Service
public class MediaProcessServiceImpl extends ServiceImpl<MediaProcessMapper,
        MediaProcess> implements MediaProcessService {
    @Autowired
    MediaProcessHistoryMapper mediaProcessHistoryMapper;

    /**
     * 根据分片序号和分片总数以及查询数量，查询视频待处理任务
     * @param shardIndex
     * @param shardTotal
     * @param count
     * @return
     */
    @Override
    public List<MediaProcess> selectListByShardIndex(Integer shardIndex,
            Integer shardTotal, Integer count,String taskType) {
        List<MediaProcess> list = this.baseMapper.selectListByShardIndex(
                shardIndex, shardTotal, count,taskType);
//        System.out.println(list);
        return list;
    }

    /**
     * 处理视频待处理任务记录
     * @param mediaProcess
     */
    @Override
    public void handleMediaProcess(MediaProcess mediaProcess) {
        //首先判断是更新还是新增
        if(mediaProcess == null)    return;
        if(mediaProcess.getId() == null){
            //新增
            save(mediaProcess);
            return;
        }
        //不是新增就是更新，判断是处理成功还是处理失败
        if(mediaProcess.getStatus().equals("2")){
            //处理成功，删除当前待处理任务
            removeById(mediaProcess.getId());
            //向历史处理任务表新增当前记录
            MediaProcessHistory mediaProcessHistory = new MediaProcessHistory();
            BeanUtils.copyProperties(mediaProcess,mediaProcessHistory);
            mediaProcessHistoryMapper.insert(mediaProcessHistory);
            return;
        }
        //处理失败，直接更新待处理任务记录
        updateById(mediaProcess);
    }

    /**
     * 开启一个任务，更新待处理任务的状态
     * @param id
     * @return
     */
    @Override
    public Boolean startTask(Long id) {
        return this.baseMapper.startTack(id) > 0;
    }

    /**
     * 生成视频待处理任务
     * @param fileMd5
     * @param taskType
     * @return
     */
    @Override
    public MediaProcess recordTask(String bucket,String filePath,
                                     String fileMd5, String taskType) {
        //首先判断当前待处理任务是否存在
        MediaProcess mediaProcess = getOne(new LambdaQueryWrapper<MediaProcess>()
                .eq(MediaProcess::getFileId,fileMd5)
                .eq(MediaProcess::getTaskType,taskType)
                .lt(MediaProcess::getFailCount,3));
        if(mediaProcess == null){
            mediaProcess = new MediaProcess();
            mediaProcess.setFileId(fileMd5);
            mediaProcess.setFilename(fileMd5);
            mediaProcess.setBucket(bucket);
            mediaProcess.setFilePath(filePath);
            mediaProcess.setStatus("4");
            mediaProcess.setBeginDate(LocalDateTime.now());
            mediaProcess.setTaskType("uploadChunk");
            mediaProcess.setFailCount(0);
            mediaProcess.setUrl("/" + bucket + "/" + filePath);
        }else{
            mediaProcess.setStatus("4");
        }
        handleMediaProcess(mediaProcess);
        return mediaProcess;
    }

    /**
     * 完成任务
     * @param fileMd5
     * @param taskType
     */
    @Override
    public void finishTask(String fileMd5, String taskType) {
        //首先根据fileMd5和taskType把对应的任务记录查出来
        MediaProcess mediaProcess = getOne(new LambdaQueryWrapper<MediaProcess>()
                .eq(MediaProcess::getFileId,fileMd5)
                .eq(MediaProcess::getTaskType,taskType)
                .lt(MediaProcess::getFailCount,3));
        //然后更新任务记录
        mediaProcess.setStatus("2");
        mediaProcess.setFinishDate(LocalDateTime.now());
        handleMediaProcess(mediaProcess);
    }

    @Override
    public Long getMaxId() {
        return this.baseMapper.getMaxId();
    }
}
